//
// Created by ftd on 2021/8/19.
// 房间管理类
// 房间对象存储在一个map里，因为在这一步只是做增删查数据操作，不对数据本身做任何
// 操作，操作执行速度很快，所以并发操作时用了一个自旋锁，在数据取出之后，通过对数
// 据里的锁进行加锁操作，在修改数据。这里是一些业务逻辑的相关操作，操作执行速度不
// 是很快，所以用了互斥锁。每次操作会用到两把锁的目的主要是为了操作不是相同的房间
// 时，可以做到并发运行。如果只加一个map的锁，将导致多线程变成串行运行，失去使用
// 多线程意义
//
//

#ifndef DEMO_ROOM_MANAGER_H
#define DEMO_ROOM_MANAGER_H
#include <map>
#include <mutex>
#include <memory>
#include <atomic>
#include "protocol//protocol.h"

enum RoomStatus : int8_t {
    // 打开状态
    kOpemStatus,
    // 关闭状态
    kCloseStatus,
};

//模拟房间相关操作，正常房间应该抽象成一个类，处理所有房间相关信息
struct RoomInfo {
    std::mutex  mtx;
    //房间状态
    RoomStatus room_status;
    int room_id;
    // 进入最低分数限制
    int join_score_lower_limit;
    // 进入最低等级限制
    int join_level_lower_limit;
    // 桌子数量
    int tables_cnt;
};

using RoomInfoPtr = std::shared_ptr<RoomInfo>;

class RoomManager {
public:
    ~RoomManager();
    RoomManager(const RoomManager&) = delete;
    RoomManager& operator= (const RoomManager&) = delete;
    static RoomManager& Instance();

    // 开启房间
    void OnOpenRoomOperate(OpenRoomOperate* open_oper);
    // 修改房间
    void OnModifyRoomOperate(ModifyRoomOperate* modify_oper);
    // 重启房间
    void OnRestartRoomOperate(RestartRoomOperate* open_oper);
    // 删除房间
    void OnDeleteRoomOperate(DeleteRoomOperate* open_oper);
    // 关闭房间
    void OnCloseRoomOperate(CloseRoomOperate* open_oper);
private:
    RoomManager();
    // 获取某个房间信息
    void GetRoomInfo(int room_id, RoomInfoPtr* room_info);

    // k roomid
    std::map<int, RoomInfoPtr> rooms_info_;
    std::atomic_flag flag_;
    int spin_cnt_;
};


#endif //DEMO_ROOM_MANAGER_H
